/*
 * StepItem
 * 
 * versvion 1.0
 * 
 * 15.05.2009
 * 
 * Copyright (c) StrongQA, Inc.
 * All rights reserved.
 *
 * This software is the confidential and proprietary information of StrongQA, Inc.
 * You shall not disclose such Confidential Information and shall use it only in
 * accordance with the terms of the license agreement you entered into
 * with StronQA.Inc.
 *
 */

package reporting;

import java.util.*;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import static util.ConstantCollection.*;
import util.*;

/**
 * @author Roman I.
 *
 */

public class ReportEngineNew {	
	
	/**
	 * object Instance of class ReportEngineNew
	 */
	private static final ReportEngineNew INSTANCE = new ReportEngineNew();		
	
	/**
	 * collection that contains names of reports 
	 */
	private HashMap dictReports = new HashMap();	
	private Util u = new Util();		
	
	/**
	 * object tc contains all properties of tests
	 */
	private TestConfiguration tc = TestConfiguration.getInstance();	
	
	/**
	 * variable step contains step of testcase 
	 */
	private TCStep step;
	
	/**
	 * variable lastStepId is numerator of testcase's steps
	 */
	private Integer lastStepId = 0;
	
	/**
	 * variable lastStepTime contains time of last testcase's steps
	 */
	private Date lastStepTime = new Date();
		
	/**
	 * manage reports, determines all actions, that related with reports
	 */
	private ReportEngineNew() {		
		FileWork fw = FileWork.getInstance();
		String headerText = "";
		Util u = new Util();
		
		headerText = "-------------------------------------------------------------------------------------\n" ;
		headerText = headerText + "Test title:\t" + tc.getEnv("_testtitle") + "\n";
		headerText = headerText + "Test name:\t" + tc.getEnv("_testname") + "\n";
		headerText = headerText + "Time zone:\t" + u.getTimeZone() + "\n";
		headerText = headerText + "Text log started:\t" + u.getDateTimeNow() + ".\n";
		headerText = headerText + "-------------------------------------------------------------------------------------\n" ;
			
		addToConsole(headerText);
		
		if(!fw.existsFileOrDir("log")){
			fw.createDir("log");
		}
		
		String tempPath = "log/" + tc.getEnv("_testname") + "/";
		
		if(!fw.existsFileOrDir(tempPath)){
			fw.createDir(tempPath);
		}
		
		DateFormat dateFormat = new SimpleDateFormat("yyyy_MM_dd_HH_mm_ss");
        Date date = new Date();
        String datetime = dateFormat.format(date);
        tempPath = tempPath + datetime + "/";       	
        
		if(!fw.existsFileOrDir(tempPath)){
			fw.createDir(tempPath);
		}
		tc.setEnv("_logpath", tempPath);
		
		//Add reports
		String [] temppair = null;
		String [] temp = null;
		temppair = tc.getEnv("appliedreports").split("\\;");
		if (temppair.length == 0){
			System.out.println("Please, set 'appliedreports' variable correctly in configuration file!");
		}
		
		for (int i = 0 ; i < temppair.length ; i++) {
		  temp = temppair[i].split("\\@");
		  if (temp.length == 2){
			  addReport(temp[0], temp[1]);
		  }  
		}		
	}
	
	/**
	 * @return object Instance of class ReportEngineNew
	 */
	public static ReportEngineNew getInstance() {
	      return INSTANCE;
	} 
	
    /**
	 * @return dictReports - collection that contains names of reports 
	 */
	public HashMap getDictReports() {
		return dictReports;
	}
	
    /**
     * @return step of testcase
     */
    public TCStep getstep() {
    	return step;
    }
    
	/**
	 * Add element to the collection that contains names of reports (dictReports).
	 * @param dictReports - collection that contains names of reports 
	 */
	private void addElementToDictReports(String key, XReport value) {
		dictReports.put(key, value);
    }	
	
    /**
     * Add new report, type can be html, txt or console.
     * @param typeReport type of record, can be txt, html etc.
     * @param nameReport simple name of report
     */
    public void addReport(String typeReport, String nameReport){
    	typeReport = typeReport.toLowerCase();
    	typeReport = typeReport.trim();
    	String key;
    	TemplateReport reporterX;
   		if (typeReport.contentEquals("html")){
   			key = typeReport.concat("_").concat(nameReport);   
			if(!getDictReports().containsKey(key)){
				reporterX = new HtmlReport(nameReport);
			}
			else{
				System.out.println("There is no this type");
				return;
			}
				
		}
		else if(typeReport.contentEquals("txt")){
				key = typeReport.concat("_").concat(nameReport);
				if(!getDictReports().containsKey(key)){
					reporterX = new TxtReport(nameReport);
				}
				else{
					System.out.println("There is no this type");
					return;
				}
		}
		else if(typeReport.contentEquals("console")){
			key = typeReport.concat("_").concat(nameReport);
			if(!getDictReports().containsKey(key)){
				reporterX = new ConsoleReport(nameReport);
			}
			else{
				System.out.println("There is no this type");
				return;
			}
		}
		else{
			System.out.println("addReport:: Type '" + typeReport + "' was not found!");
			return;
		}
   		
   		addElementToDictReports(key, reporterX);
			
    }	
    
    private String createSnapshot(int msgID){
    	return "";
    }
    
    
    /**
     * Add new step of test case, and passes it to addToConsole method.
     * @param id Identifire
     * @param name of actions, title of message
     */
    public void newStep(String id, String name) {
    	TCStep step = new TCStep(id, name);
    	
    	addToConsole("STEP:" + id + ". (" + u.getTime(step.getTime()) + ")" + step.getName());
    	this.step = step; 
    }
    
    /**
     * Create new step (with Id) of test case, and passes it to addToConsole method.
     * @param name of actions, title of message
     */
    public void newStep(String name) {
    	Integer id = lastStepId + 1;
    	TCStep step = new TCStep(id.toString(), name);
    	
    	addToConsole("STEP:" + step.getId() + ". (" + u.getTime(step.getTime()) + ")" + step.getName());
    	this.step = step;
    	lastStepId = id;
    }
    
    public void reportStep() {
    	addToConsole("SUMMARY: " + getStatusName(step.getStatus()) + "\n");
    	
    	Map.Entry<String, XReport> entry = null;
    	Iterator it = getDictReports().entrySet().iterator();
    	while(it.hasNext()){
             entry = (Map.Entry)it.next();
             XReport report = entry.getValue();
             report.reportStep(step);
        }
    }
    
    /**
     * Add new action of test case, and passes it to addToConsole method.
     * @param description of action
     */
    public void newAction(String description) {
    	addToConsole("	ACTION: " + description);
    	step.addToCollection("action", description);
    }
    
    /**
     * Add new check of test case, and passes it to addToConsole method.
     * @param description of action
     */
    public void newCheck(String description) {
    	addToConsole("	CHECK: " + description);
    	step.addToCollection("cp", description);
    }
    
    /**
     * Define status of action, and passes it to addToConsole method.
     * @param status get status from list "STATUS_INFO, STATUS_UNCHECKED, STATUS_DONE, STATUS_PASS"
     */
    public void setStatus(Integer status) {
    	addToConsole("	STATUS: " + getStatusName(status));
    	step.setItemStatus(status, "");
    }
    
    /**
     * Define status of action, and passes it to addToConsole method.
     * with the text of error or warning.
     * @param status get status from list "STATUS_INFO, STATUS_UNCHECKED, STATUS_DONE, STATUS_PASS"
     * @param text of error or warning
     */
    public void setStatus(Integer status, String text) {
    	addToConsole("	STATUS: " + getStatusName(status) +"(" + text + ")");
    	step.setItemStatus(status, text);
    }
    
    /**
     * Display on console reports, steps, actions, statuses etc.
     * @param text of report that display in console
     */
    private void addToConsole(String text) {
    	if (tc.getEnv("addstepstoconsole").toLowerCase().contentEquals("true")) {
    		System.out.println(text);
    	}
    }
    
}